#include "modbusmaster.h"
#include "ui_modbusmaster.h"
#include <QDebug>
#include <sstream>
#include <string>

using namespace std;

union server Udata;

modbusMaster::modbusMaster(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::modbusMaster)
{
    ui->setupUi(this);

// //创建数据库
//    if(!(Db_modbus.CreateConnect()))
//    qDebug() << "error" <<endl;

    m_mode=Tcp;

   if(m_mode==Tcp)
     m_master = new QModbusTcpServer(this);
   else
     m_master = new QModbusRtuSerialSlave(this);


   if (ui->IP->text().isEmpty())
       ui->IP->setText(QLatin1Literal("127.0.0.1"));
   if (ui->Port->text().isEmpty())
       ui->Port->setText(QLatin1Literal("502"));
   ui->address->setText("1");

   initModbusNetworkMaster(ui->IP->text(), ui->Port->text().toInt());

}

modbusMaster::~modbusMaster()
{
    delete ui;
    if (m_master)
        m_master->disconnectDevice();
    delete m_master;

}


bool modbusMaster::initModbusSerialMaster(QString portName, qint32 baudRate, QSerialPort::DataBits dataBits,
                                   QSerialPort::Parity parity,
                                   QSerialPort::StopBits stopBits)
{
  //  m_master = new QModbusRtuSerialSlave(this);

    m_mode = Serial;

    if(!m_master)
    {
        return 0;
    }

    QModbusDataUnitMap reg;
    reg.insert(QModbusDataUnit::Coils, { QModbusDataUnit::Coils, 0, 10 });
    reg.insert(QModbusDataUnit::DiscreteInputs, { QModbusDataUnit::DiscreteInputs, 0, 10 });
    reg.insert(QModbusDataUnit::InputRegisters, { QModbusDataUnit::InputRegisters, 0, 10 });
    reg.insert(QModbusDataUnit::HoldingRegisters, { QModbusDataUnit::HoldingRegisters, 0, 10 });

    m_master->setMap(reg);

    m_master->setConnectionParameter(QModbusDevice::SerialPortNameParameter,
                                    portName);
    m_master->setConnectionParameter(QModbusDevice::SerialBaudRateParameter,
                                    baudRate);
    m_master->setConnectionParameter(QModbusDevice::SerialDataBitsParameter,
                                    dataBits);
    m_master->setConnectionParameter(QModbusDevice::SerialParityParameter,
                                    parity);
    m_master->setConnectionParameter(QModbusDevice::SerialStopBitsParameter,
                                    stopBits);


    //更新寄存器值
    connect(m_master,&QModbusServer::dataWritten,this,
            &modbusMaster::updateData);
    //更新连接状态
    connect(m_master, &QModbusServer::stateChanged,
            this, &modbusMaster::onStateChanged);
    //错误发生
    connect(m_master, &QModbusServer::errorOccurred,
            this, &modbusMaster::handleDeviceError);
    return  1;

}

bool modbusMaster::initModbusNetworkMaster(QString address, int port)
{
  //  m_master = new QModbusTcpServer(this);

    m_mode = Tcp;

    if(!m_master)
    {
        return 0;
    }

    QModbusDataUnitMap reg;
  //  reg.insert(QModbusDataUnit::Coils, { QModbusDataUnit::Coils, 0, 10 });
 //   reg.insert(QModbusDataUnit::DiscreteInputs, { QModbusDataUnit::DiscreteInputs, 0, 10 });
 //   reg.insert(QModbusDataUnit::InputRegisters, { QModbusDataUnit::InputRegisters, 0, 10 });
    reg.insert(QModbusDataUnit::HoldingRegisters, { QModbusDataUnit::HoldingRegisters, 0, 13 });

    m_master->setMap(reg);

    m_master->setConnectionParameter(QModbusDevice::NetworkAddressParameter,address);
    m_master->setConnectionParameter(QModbusDevice::NetworkPortParameter,port);

    //更新寄存器值
    connect(m_master,&QModbusServer::dataWritten,this,
            &modbusMaster::updateData);
    //更新连接状态
    connect(m_master, &QModbusServer::stateChanged,
            this, &modbusMaster::onStateChanged);
    //错误发生
    connect(m_master, &QModbusServer::errorOccurred,
            this, &modbusMaster::handleDeviceError);

}

bool modbusMaster::connectDevice()
{
    return m_master->connectDevice();
}

void modbusMaster::updateData(QModbusDataUnit::RegisterType table, int address, int size)
{
//    union server
//    {
//        float Data[6];
//        quint16 receive_data[13];
//    }Udata;

    if(table==QModbusDataUnit::HoldingRegisters)
   {
        for (int i = 0; i < size; ++i)
        {
             m_master->data(QModbusDataUnit::HoldingRegisters, address + i, &Udata.receive_data[i]);//得到数据后做出显示
        }
    }


    if( Udata.receive_data[12] == 255)//保证信号是来自客户端的才更新显示
    {
        for(int j=0;j<6;j++)
        {
          QString s;
            switch (j){
            case 0:
                s = QString::number(Udata.Data[j],10,5);
                break;
            case 1:
                 s = QString::number(Udata.Data[j],10,5);
                break;
            case 2:
                 s = QString::number(Udata.Data[j],10,2);
                break;
            case 3:
                 s = QString::number(Udata.Data[j],10,2);
                break;
            case 4:
                s = QString::number(Udata.Data[j],10,2);
                break;
            case 5:
                 s = QString::number(Udata.Data[j],10,2);
                break;
             default:
                break;
            }
           // QString s = QString::number(Udata.Data[j],10,5);//int变量转QString变量 第二个参数16表示转换为16进制数
            switch (j){
            case 0:
                ui->longitude->setText(s);
                break;
            case 1:
                ui->latitude->setText(s);
                break;
            case 2:
                ui->Dive->setText(s);
                break;
            case 3:
                ui->Pitch->setText(s);
                break;
            case 4:
                ui->Roll->setText(s);
                break;
            case 5:
                ui->Yaw->setText(s);
                break;
             default:
                break;
            }
        }
        UpdataData();//更新数据到数据库
    }
 //   qDebug()<<"*****"<<endl;//<<count<<num
}

void modbusMaster::handleDeviceError(QModbusDevice::Error newError)
{
    if(newError == QModbusDevice::NoError || !m_master)
        return;
    emit error_signal(m_master->errorString());
}

void modbusMaster::onStateChanged(int state)
{
    if(state == QModbusDevice::UnconnectedState)
      ui->connectButton->setText(tr("Connect")); // emit stateChanged_signal(0);
    else if(state == QModbusDevice::ConnectedState)
       ui->connectButton->setText(tr("Disconnect"));//  emit stateChanged_signal(1);
}


void modbusMaster::on_connectButton_clicked()
{
    if (!m_master)//检查是否创建modbus master成功
        return;
    statusBar()->clearMessage();

    if (m_master->state() != QModbusDevice::ConnectedState) {//如果处在非连接状态，进行连接
        //进行TCP连接
        m_master->setConnectionParameter(QModbusDevice::NetworkPortParameter, ui->Port->text().toInt());
        m_master->setConnectionParameter(QModbusDevice::NetworkAddressParameter, ui->IP->text());
        m_master->setServerAddress(ui->address->text().toInt());
        if (!m_master->connectDevice()) {
            statusBar()->showMessage(tr("Connect failed: ") + m_master->errorString(), 5000);
        }
    }else{//处在连接状态进行断开连接的操作
        m_master->disconnectDevice();
    }
}

void modbusMaster::on_writeButton_clicked()
{
    QString str = ui->textEdit->toPlainText();
    QString str2 = str.replace(" ","");//去掉空格

    for(int i = 0 ;i < 10;i++)
    {
       int j = 2*i;
       QString str1 = str2.mid(j,2);
       bool ok;
       quint16 hex = str1.toInt(&ok,16);//
       ok = m_master->setData(QModbusDataUnit::HoldingRegisters, i, hex);
    }
   m_master->setData(QModbusDataUnit::HoldingRegisters, 10, (str.length()-1)/2+1);
}

void modbusMaster::on_dataButton_clicked()
{
 data_base = new DataBase();

    data_base->show();

}
